import 'package:dartkit/dartkit.dart';
import 'package:postgres/postgres.dart';

part 'args.dart';

/// 当操作其他数据库时，需要连接管理数据库，它的名字是固定的
const String _admin = "postgres";

class DatabaseKit {
  /// 创建一个新的数据库（使用管理库来操作）
  /// 如果已存在，则不进行任何操作
  static Future<void> create(String name) async {
    // 连接管理数据库，并创建新数据库
    final connAdmin = await open(_admin);
    try {
      await connAdmin.execute('CREATE DATABASE $name');
    } on ServerException catch (e) {
      // 如果是数据库已存在的话，则压下错误
      final bool alreadyExists = e.code == "42P04";
      if (!alreadyExists) rethrow;
    } catch (_) {
      rethrow;
    }
    // 关闭连接
    await connAdmin.close();
  }

  /// 根据已经配置好的信息，传入一个字符串，获得一个连接的实例
  /// 请注意：首先需要创建一个数据库
  static Future<Connection> open(String name) async {
    final connection = await Connection.open(
        Endpoint(
          host: argPostgres.value.host,
          database: name,
          username: argPostgres.value.userName,
          password: argPostgres.value.password,
        ),
        settings: ConnectionSettings(
          sslMode: SslMode.disable,
        ));
    return connection;
  }

  /// 获取当前所有数据库的名字
  static Future<List<String>> get databases async {
    // 连接管理数据库
    final connAdmin = await open(_admin);
    // 执行获取名字的操作，并将结果转化为List<String>
    final results = await connAdmin
        .execute('SELECT datname FROM pg_database WHERE datistemplate = false');
    List<String> names = results.map((row) => row[0] as String).toList();
    // 关闭连接，并返回结果
    await connAdmin.close();
    return names;
  }

  /// 删除一个现有的数据库（使用管理库操作）
  /// 如果不存在的话，则不做任何操作
  static Future<void> delete(String name) async {
    // 连接管理数据库，并创建新数据库
    final connAdmin = await open(_admin);
    await connAdmin.execute('DROP DATABASE IF EXISTS $name');
    // 关闭连接
    await connAdmin.close();
  }
}
